#include "daemon_sub_process.h"
#include "log/log.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/reboot.h>
#include <signal.h>


subProcess *daemon_subProcess_init(char *sub_cmd)
{
    subProcess *sp = (subProcess *)malloc(sizeof(subProcess));
    sp->cmd_param = sub_cmd;
    sp->pid = 0;
    sp->fail_count = 0;
    return sp;
}

int daemon_subProcess_checkStart(subProcess *sp)
{
    // 检查子进程是否正在在运行中， 如果是则直接返回
    int status;
        // waitpid不会真等子进程结束，如果子进程还在运行中，waitpid会立即返回0
        // 如果子进程已结束，将进程结束时的状态保存到status中
    if (sp->pid>0 && waitpid(sp->pid, &status, WNOHANG) == 0)
    {
        log_debug("进程(%s) 正在运行中...", sp->cmd_param);
        return 0;
    }
    // 子进程是失败结束的， 让失败次数加1，如果失败次数大于最大值，则重启系统
    if (status==-1)
    {
        sp->fail_count++;
        if (sp->fail_count>MAX_FAIL_COUNT)
        {
            reboot(RB_AUTOBOOT);
        }
    }
    // 创建子进程，在子进程中执行程序
    sp->pid = fork();//创建子进程 ，在子进程中返回0，在父进程中返回子进程的pid
    if (sp->pid == 0)
    {
        // 子进程执行
        log_debug("在子进程中准备执行程序(%s)", sp->cmd_param);
        char *argv[] = {EXE_PATH, sp->cmd_param, NULL};
        execve(EXE_PATH, argv, NULL);
        log_error("子进程执行程序(%s)失败", sp->cmd_param);

        _exit(EXIT_FAILURE);
    }

    return 0;
}

void daemon_subProcess_stop(subProcess *sp)
{
    // 杀死子进程
    kill(sp->pid, SIGTERM);
    // 等待子进程结束
    waitpid(sp->pid, NULL, 0);//waitpid会阻塞父进程，直到子进程结束
    // 释放内存
    free(sp);
}
